package org.example.util;

import javax.websocket.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.Callable;
import java.util.function.Consumer;

public class WebSocketUtils {

    public interface onMessageCallBack extends Callable<Void> {
        void call(String msg) throws Exception;

        @Override
        Void call() throws Exception;
    }

    public interface WSClient {
        void sendMessage(String msg) throws IOException;
        void sendMessageAsync(String msg);
        void close() throws IOException;
    }

    @ClientEndpoint
    static class WSClientImpl implements WSClient {
        private final Session session;
        private final Consumer<String> onMessageCallback;

        WSClientImpl(URI uri, Consumer<String> onMessageCallback) throws DeploymentException, IOException {
            this.session = ContainerProvider.getWebSocketContainer().connectToServer(this, uri);
            this.onMessageCallback = onMessageCallback;
        }

        @OnMessage
        public void onMessage(String msg) throws Exception {
            onMessageCallback.accept(msg);
        }

        @Override
        public void sendMessageAsync(String msg) {
            session.getAsyncRemote().sendText(msg);
        }

        @Override
        public void sendMessage(String msg) throws IOException {
            session.getBasicRemote().sendText(msg);
        }

        @Override
        public void close() throws IOException {
            session.close();
        }
    }

    public static WSClient createClient(String uri, Consumer<String> onMsgCallback) throws DeploymentException, IOException, URISyntaxException {
        return new WSClientImpl(new URI(uri), onMsgCallback);
    }
}
